package com.lsh.payment.core.strategy.payment;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lsh.payment.core.constant.BusinessConstant;
import com.lsh.payment.core.constant.RedisKeyConstant;
import com.lsh.payment.core.model.payenum.TradeType;
import com.lsh.payment.core.model.payenum.cmpay.CmBizResultCode;
import com.lsh.payment.core.model.payenum.cmpay.CmResultCode;
import com.lsh.payment.core.service.config.RedisConfigService;
import com.lsh.payment.core.strategy.config.CmPayConfig;
import com.lsh.payment.core.strategy.config.IpcPayConfig;
import com.lsh.payment.core.strategy.vo.cmpay.CmPayResponse;
import com.lsh.payment.core.util.BigDecimalUtils;
import com.lsh.payment.core.util.pay.cm.HttpCmProxy;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Map;

import static com.lsh.payment.core.constant.BusinessConstant.CMPAY;
import static com.lsh.payment.core.constant.BusinessConstant.STRATEGY_BEAN_NAME_PREFIX;


/**
 * Project Name: lsh-payment
 *
 * @author peter
 * @date 16/11/23
 * 北京链商电子商务有限公司
 * Package
 * desc:
 */
@Component(STRATEGY_BEAN_NAME_PREFIX + CMPAY)
public class CmPayStrategy implements PayStrategy<CmPayResponse> {

    private Logger logger = LoggerFactory.getLogger(CmPayStrategy.class);

//    @Autowired
//    private RedisStringDao redisStringDao;

    @Autowired
    private RedisConfigService redisConfigService;

    @Value("${cm.notify.url}")
    private String notifyUrl;

    /**
     * 调用对应支付平台组装支付请求报文
     *
     * @param payType  传入需要的支付方式
     * @param paramMap 其他额外需要的参数
     * @return 生成的支付请求
     */
    @Override
    public CmPayResponse generatePayParams(int payType, final Map<String, String> paramMap) {
        String prefix = "请求收钱吧下单 ";
        logger.info("{}参数: {}", prefix, paramMap);
        BigDecimal amount = new BigDecimal(paramMap.get("payAmount"));
        String payPaymentNo = paramMap.get("payPaymentNo");
        int channelType = Integer.parseInt(paramMap.get("channelType"));
        String venderId = paramMap.get("venderId");
        if (StringUtils.isBlank(venderId)) {
            venderId = "0";
        }

        JSONObject data = null;
        try {
            org.json.JSONObject paramOrder = new org.json.JSONObject();

            paramOrder.put("terminal_sn", redisConfigService.getCmSnValue(RedisKeyConstant.PAY_CM_SN));
            paramOrder.put("client_sn", payPaymentNo);
            paramOrder.put("total_amount", BigDecimalUtils.yuanToFen(amount).toString());
            if (channelType == TradeType.CMWXSM.getCode()) {
                paramOrder.put("payway", "3");
            } else if (channelType == TradeType.CMALISM.getCode()) {
                paramOrder.put("payway", "1");
            }
            paramOrder.put("subject", CmPayConfig.CM_PAY_TITLE);

            paramOrder.put("operator", "LSH-SAAS-" + venderId);

            paramOrder.put("notify_url", notifyUrl);

            HttpCmProxy proxy = new HttpCmProxy(CmPayConfig.PAY_BASE);

            String result = proxy.precreate(paramOrder, redisConfigService.getCmSnValue(RedisKeyConstant.PAY_CM_SN), redisConfigService.getCmKeyValue(RedisKeyConstant.PAY_CM_KEY));

            logger.info("cm result is " + result);

            JSONObject resultJson = JSON.parseObject(result);

            Integer outResultCode = resultJson.getInteger("result_code");

            if (outResultCode != CmResultCode.C200.getCode()) {

                resultJson.getString("error_code");
                resultJson.getString("error_message");

                return this.buildRsp(data, payPaymentNo);
            }

            JSONObject bizResponse = resultJson.getJSONObject("biz_response");
            String bizResultCode = bizResponse.getString("result_code");

            if (!bizResultCode.equals(CmBizResultCode.PRECREATE_SUCCESS.getCode())) {
                bizResponse.getString("error_code");
                bizResponse.getString("error_message");

                return this.buildRsp(data, payPaymentNo);
            }

            data = bizResponse.getJSONObject("data");

        } catch (Exception e) {
            logger.error("", e);
        }

        return this.buildRsp(data, payPaymentNo);
    }


    /**
     * 下单返回值
     *
     * @param resMessage 返回结果
     * @return 支付平台返回结果
     */
    private CmPayResponse buildRsp(JSONObject resMessage, String payPaymentNo) {

        CmPayResponse response = new CmPayResponse();
        response.setCode(BusinessConstant.PAY_REQUEST_FAIL);
        response.setMsg(BusinessConstant.PAY_REQUEST_FAIL_MESSAGE);

        if (resMessage == null) {
            return response;
        }

        logger.info("收钱吧 支付流水号 {} callRsp = {}", payPaymentNo, resMessage.toJSONString());

        response.setCode(BusinessConstant.PAY_REQUEST_SUCCESS);
        JSONObject resResult = new JSONObject();
        resResult.put(IpcPayConfig.RESPONSE_BODY_QRCODE, resMessage.getString("qr_code"));
        resResult.put(IpcPayConfig.RESPONSE_BODY_TRADE_CODE, payPaymentNo);
        resResult.put("sn", resMessage.getString("sn"));
        response.setMsg(resResult.toJSONString());

        logger.info("请求收钱吧支付,支付流水-" + payPaymentNo + ", 返回:" + JSON.toJSONString(response));
        return response;
    }
}
